package com.gengzp.system.facade.impl;

import com.gengzp.common.constants.DatePatternConstants;
import com.gengzp.common.model.log.dto.OperationLogCountDto;
import com.gengzp.common.model.log.entity.SysOperationLog;
import com.gengzp.common.model.log.resp.SearchOperationLogCountResp;
import com.gengzp.common.utils.DateUtils;
import com.gengzp.common.utils.ThreadUtils;
import com.gengzp.system.facade.SysLogFacade;
import com.gengzp.system.mapper.SysOperationLogMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName SysLogFacadeImpl
 * @Description 系统日志模块门面层实现
 * @Author gengzp
 * @Date 2025/10/24 10:37
 */
@Service
public class SysLogFacadeImpl implements SysLogFacade {

    @Autowired
    private SysOperationLogMapper sysOperationLogMapper;

    @Override
    public SearchOperationLogCountResp searchOperationLogCount() {
        SearchOperationLogCountResp resp = new SearchOperationLogCountResp();
        resp.setTodayOperationLogCount(0);
        resp.setHighFrequencyOperationLogs(Lists.newArrayList());

        Date currentDate = new Date();

        ThreadUtils.batchExecute(() -> {
            // 今日的起始时间
            Date todayStartTime = DateUtils.Str2Date(
                    DateUtils.Date2Str(currentDate, DatePatternConstants.YMD_PATTERN) + " 00:00:00",
                    DatePatternConstants.YMD_HMS_PATTERN);

            // 今日新产生的操作日志数量
            resp.setTodayOperationLogCount(
                    sysOperationLogMapper.selectSysOperationLogCountByCreatedTimeStart(todayStartTime));
        }, () -> {
            // 7天前
            Date beforeOneStartTime = new Date(currentDate.getTime() - 7 * 24 * 60 * 60 * 1000L);

            // 一个星期内的高频调用接口
            List<SysOperationLog> sysOperationLogs = sysOperationLogMapper
                    .selectSysOperationLogsByCreatedTimeStart(beforeOneStartTime);
            if (CollectionUtils.isNotEmpty(sysOperationLogs)) {
                // 根据接口uri进行分组  key: uri  value: 对应的SysOperationLog列表
                Map<String, List<SysOperationLog>> uriMap = sysOperationLogs.stream().collect(Collectors.groupingBy(SysOperationLog::getUri));
                // uri对应日志数量映射
                Map<String, Integer> uriCountMap = Maps.newHashMap();
                for (Map.Entry<String, List<SysOperationLog>> entry : uriMap.entrySet()) {
                    uriCountMap.put(entry.getKey(), entry.getValue().size());
                }

                // 按数量（value）降序排序，取前3个，结果保留为有序Map（按排序后的顺序）
                resp.getHighFrequencyOperationLogs().addAll(uriCountMap.entrySet().stream()
                        // 按value降序排序（reversed()反转默认的升序为降序）
                        .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                        // 只保留前3个（若有并列，也仅取前3）
                        .limit(3)
                        .map(v -> {
                            SysOperationLog sysOperationLog = uriMap.get(v.getKey()).get(0);
                            OperationLogCountDto dto = new OperationLogCountDto();
                            dto.setUri(sysOperationLog.getUri());
                            dto.setOperationDescription(sysOperationLog.getRequestDescription());
                            dto.setInvokeCount(v.getValue());
                            return dto;
                        }).toList());
            }
        });

        return resp;
    }

}
